package com.pactera.jep.service.sys.web.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.pactera.jep.commons.DateUtils;
import com.pactera.jep.core.security.token.Token;
import com.pactera.jep.core.security.token.TokenService;
import com.pactera.jep.core.security.token.impl.TokenBuilder;
import com.pactera.jep.sys.service.AuthorizationService;
import com.pactera.jep.sys.service.MenuService;
import com.pactera.jep.sys.service.StaffService;
import com.pactera.jep.sys.service.UserService;
import com.pactera.jep.web.code.WebHeaderCode;

@RestController
public class LoginRestController {

	private static Logger log = LoggerFactory.getLogger(LoginRestController.class);

	@Autowired
	UserService userService;

	@Autowired
	StaffService staffService;

	@Autowired
	TokenService tokenService;

	@Autowired
	AuthorizationService authorizationService;

	@Autowired
	MenuService menuService;

	/**
	 * 要求进行登录，对于任意未登录用户发起的请求都将会被重定向到这个接口用来要求用户进行登录
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/requireLogin", method = { RequestMethod.GET, RequestMethod.POST })
	public void requireLogin(HttpServletRequest request, HttpServletResponse response) {
		// 首先设置响应头相关属性
		response.setContentType("application/json;charset=UTF-8");
		response.setStatus(HttpServletResponse.SC_FORBIDDEN);
		response.setLocale(Locale.CHINA);
		// 获取PrintWriter向请求写回响应
		try (PrintWriter writer = response.getWriter()) {
			String message = "{\"success\":\"false\", \"msg\":\"请登录后执行此操作!\"}";
			writer.write(message);
			writer.flush();
		} catch (IOException e) {
			log.error("写回响应时出现异常：{}", e.getMessage(), e);
		}
	}

	@RequestMapping(value = "/sso", method = { RequestMethod.GET })
	public void sso(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
		if (request.getParameter("returnUrl") != null) {
			String location = request.getParameter("returnUrl");
			if (location.startsWith("http")) {
				if (location.contains("~")) {
					location = location.replaceAll("~", "#");
				}
				// zuul_session是从zuul中将请求本次请求到zuul的sessionid传递过来，这样使得前端可以获取到这个session从而使得后面的请求正常的通过验证
				String zuulSessionId = request.getHeader("zuul_session");
				String token = JSON.parseObject(request.getHeader("auth_info")).getString("token");
				log.debug("zuul_session is {}", zuulSessionId);
				// 拿到前面生成的token
				log.debug("token is {}", token);
				response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
				response.setHeader("Location", location + "?zuul_session=" + zuulSessionId + "&access_token=" + token);
				return;
			} else {
				log.debug("请求中带有的参数不合法！");
				return;
			}
		} else {
			String returnUrl = request.getHeader("return_url");
			// 如果在header中获取到了return_url，那么直接跳转至return_url
			if (StringUtils.isNotBlank(returnUrl)) {
				response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
				response.setHeader("Location", returnUrl.replaceAll("~", "#"));
			} else {
				// 如果请求中不带有任何returnUrl的数据，那么响应一个401
				response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			}
		}
		log.debug("请求参数中不带有返回地址，不进行任何处理...");
	}
	
	/**
	 * SSO注销用，一定要有一个接口，否则zuul将直接响应404而不会将请求交给filter进行处理
	 */
	@RequestMapping(value="/doLogout", method = {RequestMethod.GET})
	public void doLogout(HttpServletRequest request, HttpServletResponse response) {
		
	}

	/**
	 * 刷新token
	 * 
	 * @param request
	 * @param userToken
	 * @return
	 */
	@PostMapping("/login/refresh")
	public Map<String, Object> refresh(HttpServletRequest request,
			@RequestHeader(WebHeaderCode.X_USER_TOKEN) String userToken) {
		Map<String, Object> map = new HashMap<>();
		map.put("success", true);
		if (StringUtils.isEmpty(userToken)) {
			map.put("success", false);
			map.put("msg", "token is empty");
		} else {
			try {
				Token token = tokenService.decode(userToken);
				Token newToken = TokenBuilder.newTokenBuilder(token.getId(), token.getCategory(), token.getAction())
						.username(token.getUsername()).property("loginTime", DateUtils.formatDateTime(new Date()))
						.expirationInMinutes(30).build();
				map.put("token", tokenService.encode(newToken));
			} catch (Exception ex) {
				log.error("token is invalid", ex);
				map.put("success", false);
			}
		}

		return map;
	}
}
